package com.zw.mes.module.tecard.service;

import com.zw.mes.entity.flow.FlowRoute;
import com.zw.mes.entity.flow.FlowSheet;
import com.zw.mes.entity.technology.ReceiveSum;
import com.zw.mes.entity.technology.Tecard;
import com.zw.mes.module.prodtaskmanager.entity.ProdOrd;
import com.zw.mes.module.prodtaskmanager.entity.VwProject;
import com.zw.mes.module.system.service.LogService;
import com.zw.mes.module.tecard.mapper.TecardMapper;
import com.zw.mes.module.tecard.repository.FlowDetialRepository;
import com.zw.mes.module.tecard.repository.FlowSheetRepository;
import com.zw.mes.module.technology.repository.ReceiveSumRepository;
import com.zw.mes.util.ShiroUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;


import static com.zw.mes.util.BeanUtil.getNullPropertyNames;


/**
 * @author mayongfeng
 * @version 1.0.0
 * @ClassName TecardService.java
 * @Description TODO
 * @createTime 2021年03月11日 10:28:00
 */
@Service
@SuppressWarnings("all")
public class TecardService {

    @Autowired
    private TecardMapper tecardMapper;
    @Autowired
    private FlowSheetRepository flowSheetRepository;
    @Autowired
    private FlowDetialRepository flowDetialRepository;
    @Autowired
    private LogService logService;
    @Autowired
    private ReceiveSumRepository receiveSumRepository;

    /**
     * 旧 查询工艺卡接收列表页
     */
    public List<Tecard> getCardRevice(Tecard tecard) {
        return tecardMapper.getCardRevice(tecard);
    }

    /**
     * 新 查询工艺卡接收列表页
     */
    public List<Tecard> getGroupByCardRevice(Tecard tecard) {
        return tecardMapper.getGroupByCardRevice(tecard);
    }

    /**
     * 查询项目下所有图号的工艺卡列表
     */
    public List<Tecard> getMakeDetail(Tecard tecard) {
        List<Tecard> tecardList = new ArrayList<>();
        /** 判断工艺卡是否是变更的0=未变更,1=已变更*/
//        if(tecard.getProdChange()==0){
//            if(tecard.getRecStatus() == 0){
//                tecardList = tecardMapper.getMakeDetail(tecard);
//            }else{
//                tecardList = tecardMapper.getMakeDetailOld(tecard);
//            }
//        }else if(tecard.getProdChange()==1){
//            if(tecard.getRecStatus() == 0){
//                tecardList = tecardMapper.getMakeDetailcha(tecard);
//            }else{
//                tecardList = tecardMapper.getMakeDetailOld(tecard);
//            }
//        }
        if (tecard.getRecStatus() == 0) {
            tecardList = tecardMapper.getMakeDetailcha(tecard);
        } else {
            // tecardList = tecardMapper.getMakeDetailOld(tecard);
            tecardList = tecardMapper.getMakeDetailLocal(tecard);
        }
        //tecardList = tecardMapper.getVwCraCardSheetByCndition(condition);
        return tecardList;
    }

    /**
     * @methodName: getCardNum
     * @description: 获取工艺卡数量，领导因与工艺卡打印对数量而显示的，
     * 此查询条件与上面的selectMakeDetail方法的查询条件要相同。
     * @param: tecard
     * @return： com.zw.mes.common.JsonResult
     * @exception：
     * @author： 徐一贺 tel:18341916590
     * @designer： 陈欣
     * @leader： 陈欣 tel:18104194240
     * @date： 2021/5/28 16:14
     * @office: 智能控制设计科
     * @research institute： 智能控制设计所
     * @department： 机械设计院
     * @company: 辽宁忠旺机械设备制造有限公司
     * @group： 忠旺集团
     * @version: 1.0
     */
    public Integer getCardNum(Tecard tecard) {
        Integer resultCount = 0;
//        if(tecard.getProdChange()==0){
//            if(tecard.getRecStatus() == 0){
//                resultCount = tecardMapper.getMakeDetailCount(tecard);
//            }else{
//                resultCount = tecardMapper.getMakeDetailOldCount(tecard);
//            }
//        }else if(tecard.getProdChange()==1){
//            if(tecard.getRecStatus() == 0){
//                resultCount = tecardMapper.getMakeDetailchaCount(tecard);
//            }else{
//                resultCount = tecardMapper.getMakeDetailOldCount(tecard);
//            }
//        }
        if (tecard.getRecStatus() == 0) {
            resultCount = tecardMapper.getMakeDetailchaCount(tecard);
        } else {
            resultCount = tecardMapper.getMakeDetailOldCount(tecard);
        }
        return resultCount;
    }

    /**
     * 按主键查询主单
     */
    public Tecard getCardById(Integer id) {
        return tecardMapper.getOne(id);
    }

    /**
     * 查询图号的工艺卡明细
     */
    public List<Tecard> findCardDetailByCardId(Integer id) {
        return tecardMapper.findByCardId(id);
    }

    /**
     * 按主键查询生产工艺主单
     */
    public Tecard getProdCardById(Integer id) {
        return tecardMapper.getProdCardById(id);
    }

    /**
     * 查询生产图号的工艺卡明细
     */
    public List<Tecard> findProdCardDetailByCardId(Integer id) {
        return tecardMapper.findProdCardDetailByCardId(id);
    }


    /**
     * @Author mayongfeng
     * @Date 15:19 2021/3/12
     * @Description 将pdm的工艺卡接收到生产系统里面来，修改工艺卡主表的接收状态
     **/
    @Transactional(rollbackFor = Exception.class)
    public int cardReceive(Tecard tecard) {
        logService.saveLog("接收工艺卡", "项目号：" + tecard.getProCode() +
                "-项目名称：" + tecard.getProName()
                + "-专业" + tecard.getSpecial()
                + "-部分" + tecard.getPart());

        /** 首次接收时在接收记录表里面添加记录信息*/
        ReceiveSum str = receiveSumRepository.findByProCodeAndPartAndSpecial(tecard.getProCode(), tecard.getPart(), tecard.getSpecial());
        /** 判断集合为不为null*/
        if (null == str || "".equals(str)) {
            /** 如果记录表里面为空就向记录表里面添加接收记录*/
            ReceiveSum receiveSum = new ReceiveSum();
            receiveSum.setProCode(tecard.getProCode());
            receiveSum.setProName(tecard.getProName());
            receiveSum.setProNum(Integer.parseInt(tecard.getProNum()));
            receiveSum.setPart(tecard.getPart());
            receiveSum.setSpecial(tecard.getSpecial());
            receiveSum.setOutStatus(0);
            receiveSum.setCardStatus(1);
            receiveSum.setMakeStatus(0);
            receiveSum.setPaintStatus(0);
            receiveSumRepository.save(receiveSum);
        } else if (str.getCardStatus() == 0) {
            str.setCardStatus(1);
            receiveSumRepository.save(str);
        }

        /** 接收人code*/
        tecard.setRecCode(ShiroUtils.getUser().getAccount());
        /** 接收人name*/
        tecard.setRecName(ShiroUtils.getUser().getName());
        /** 接收 0=未接收，1=已接收*/
        tecard.setRecStatus(1);
        /** 接收时间 */
        tecard.setRecTime(new Date());

        int a = receiveCard(tecard);
        if (a > 0) {
            /** 通过生产令查询生产令表*/
            int prodExeSta = tecardMapper.findProdOrd(tecard);
            if (prodExeSta == 0) {
                /** 修改生产令表里面的状态*/
                tecardMapper.updateProdOrd(tecard.getProCode());
            }
        }
//        /** 通过Id修改主表的接收状态*/
//        int i = tecardMapper.updateCardMakeSheet(tecard);
//        if(i>0){
//            int a = receiveCard(tecard);
//            if(a>0){
//                /** 通过生产令查询生产令表*/
//                int prodExeSta = tecardMapper.findProdOrd(tecard);
//                if(prodExeSta==0){
//                    /** 修改生产令表里面的状态*/
//                    tecardMapper.updateProdOrd(tecard.getProCode());
//                }
//
//            }
//
//        }
        return a;
    }

    /**
     * @Author mayongfeng
     * @Date 8:55 2021/3/17
     * @Description 将技术文件的工艺卡接收到生产系统里面来
     **/
    private int receiveCard(Tecard tecard) {
        int a = 0;
        try {
            /** 查询项目下有工艺卡的主单信息*/
            List<Tecard> craSheetList = tecardMapper.getSheetDetail(tecard);
            for (Tecard tecard1 : craSheetList) {
                if ("加工件".equals(tecard1.getMakeType())) {
                    tecard1.setCategory(1);
                } else {
                    tecard1.setCategory(2);
                }
                /** 接收人code*/
                tecard1.setRecCode(ShiroUtils.getUser().getAccount());
                /** 接收人name*/
                tecard1.setRecName(ShiroUtils.getUser().getName());
                /** 接收 0=未接收，1=已接收*/
                tecard1.setRecStatus(1);
                /** 接收时间 */
                tecard1.setRecTime(new Date());
                /** 根据变更标识判断时首次还是变更，0默认，1变更*/
                if (tecard1.getProdChange() == 0) {
                    logService.saveLog("接收正常的工艺卡", "工艺卡ID：" + tecard1.getId());
                    a = addFirst(tecard1);
                } else if (tecard1.getProdChange() == 1) {
                    logService.saveLog("接收变更的工艺卡", "工艺卡ID：" + tecard1.getId());
                    FlowSheet flowSheet = new FlowSheet();
                    /** 变更逻辑通过Id查询出生产工艺卡主表里面的数据*/
                    FlowSheet flowSheetObj = tecardMapper.findFlowSheetId(tecard1.getId());
                    if ("".equals(flowSheetObj) || null == flowSheetObj) {
                        a = addFirst(tecard1);
                    } else {
                        copy(tecard1, flowSheet);
                        flowSheet.setId(flowSheetObj.getId());
                        flowSheet.setCraSheetId(flowSheetObj.getCraSheetId());
                        flowSheet.setProdNo(tecard1.getProCode());
                        flowSheet.setProNum(Integer.parseInt(tecard1.getProNum()));
                        flowSheet.setPartId(Integer.parseInt(tecard1.getPartId()));
                        flowSheet.setWeight(Double.parseDouble(tecard1.getWeight()));
                        flowSheet.setCreateCode(tecard1.getCreateCodeOne());
                        flowSheet.setCreateName(tecard1.getCreateNameOne());
                        flowSheet.setCheckCode(tecard1.getVerifyCode());
                        flowSheet.setCheckName(tecard1.getVerifyName());
                        flowSheet.setCheckTime(tecard1.getVerifyTime());
                        flowSheet.setInvalid(flowSheetObj.getInvalid());
                        /** 通过ID修改主单信息*/
                        flowSheetRepository.save(flowSheet);
                        /** 根据主表Id先删除生产工艺卡从表的数据*/
                        Integer i = tecardMapper.deleteFlowDetail(flowSheetObj.getId());
                        /** 通过Id查询技术文件工艺卡明细表里面的明细集合*/
                        List<Tecard> byCardId = tecardMapper.findByCardId(tecard1.getId());
                        for (Tecard craPlan : byCardId) {
                            craPlan.setCardId(flowSheetObj.getId());
                            tecardMapper.addCarFlowDetail(craPlan);
                        }
                        int notRouteNum = 0;
                        /** 修改技术文件工艺卡主表里面的的接收状态*/
                        a = tecardMapper.updateCarSheet(tecard1);
                        /** 变更后的查询从表去重明细*/
                        List<Tecard> newList = byCardId.stream().filter(distinctByKey(Tecard::getOrderNo)).collect(Collectors.toList());
                        /** 通过Id查询flowRoute路线明细*/
                        List<FlowRoute> flowRoutes = tecardMapper.findFlowRoutes(flowSheet.getId());
                        for (FlowRoute flowRoute : flowRoutes) {
                            /** 状态为0的数据可以删除*/
                            if (flowRoute.getStatus().intValue() == 1) {
                                int routeNum = tecardMapper.deleteFlowRoutes(flowRoute.getId());
                            } else {
                                notRouteNum++;
                            }
                        }
                        /** 将不能修改的数据删除掉*/
                        for (int i1 = 0; i1 < notRouteNum; i1++) {
                            newList.remove(0);
                        }
                        if (newList.size() > 0) {
                            for (Tecard route1 : newList) {
                                route1.setCardId(flowSheetObj.getId());
                                tecardMapper.addCarFlowRoute(route1);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return a;
    }

    /**
     * @Author mayongfeng
     * @Date 14:23 2021/3/23
     * @Description 首次接收添加, 或者变更后的首次接收都走这一个方法.
     **/
    private int addFirst(Tecard tecard1) {
        int a;
        /** 通过Id查询工艺卡明细表里面的明细集合*/
        List<Tecard> byCardId = tecardMapper.findByCardId(tecard1.getId());
        /** 查去重明细*/
        List<Tecard> newList = byCardId.stream().filter(distinctByKey(Tecard::getOrderNo)).collect(Collectors.toList());

        /** 修改技术文件工艺卡主表里面的的接收状态*/
        a = tecardMapper.updateCarSheet(tecard1);

        /** 将技术文件的工艺卡主表保存到生产工艺卡主表*/
        tecardMapper.addCarSheet(tecard1);
        /** 将明细表里的数据添加到生产工艺卡的明细表里面*/
        for (Tecard craPlan : byCardId) {
            craPlan.setCardId(tecard1.getId());
            tecardMapper.addCarFlowDetail(craPlan);
        }
        /** 将明细表里面的路线根据路线编号去重添加到生产工艺路线表里面*/
        for (Tecard route1 : newList) {
            route1.setCardId(tecard1.getId());
            tecardMapper.addCarFlowRoute(route1);
        }
        return a;
    }

    /**
     * List集合根据对象某个属性去重
     */
    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 打印工艺卡列表
     */
    public List<FlowSheet> findWithCardQuery(Tecard tecard) {

        return tecardMapper.findWithCardQuery(tecard);
    }

    /**
     * 批量打印工艺卡
     */
    public List<Tecard> findCardListFull(Integer[] ids) {
        logService.saveLog("批量打印生产的工艺的卡", "工艺卡ID：" + ids);

        List<Tecard> byIds = tecardMapper.findByIds(ids);
        for (Tecard byId : byIds) {
            if (byId.getCreateTel() == null || "".equals(byId.getCreateTel())) {
                String createTel = tecardMapper.findCreateTel(byId.getCreateCode());
                byId.setCreateTel(createTel);
            }
        }
        return byIds;
    }

    /**
     * 复制对象，并排除空值属性
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copy(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /**
     * 根据项目号获取项目信息
     *
     * @param proCode
     * @return
     */
    public VwProject getVwProjectByProCode(String proCode) {
        return tecardMapper.getVwProjectByProCode(proCode);
    }

    /**
     * 根据项目号获取生产令列表
     *
     * @param proCode
     * @return
     */
    public List<ProdOrd> findProdOrdByProdCod(String proCode) {
        return tecardMapper.findProdOrdByProdCod(proCode);
    }

    /**
     * 根据技术文件工艺卡主表id查询生产工艺卡主表id
     *
     * @param id
     * @return
     */
    public FlowSheet getFlowSheetId(Integer id) {
        return tecardMapper.findFlowSheetId(id);
    }

    /**
     * 执行删除生产工艺卡
     *
     * @param flowSheet
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int delFlowSheetCard(FlowSheet flowSheet) {
        logService.saveLog("生产系统删除工艺卡", "接收工艺卡主键:" + flowSheet.getId() + ":" + flowSheet.getDrawNo());
        tecardMapper.updateFlowSheet(flowSheet.getId(), 1);
        tecardMapper.updateflowSheetDetail(flowSheet.getId(), 1);
        return tecardMapper.updateflowRoute(flowSheet.getId(), 1);
    }

    public int selectTecardCount() {
        return tecardMapper.selectTecardCount();
    }

    /**
     * 检测是否可以变更工艺卡
     *
     * @param tecard
     * @return
     */
    public String checkIfChangeTecCaed(Tecard tecard) {
        String result = "";
        /** 查询项目下有工艺卡的主单信息*/
        List<Tecard> craSheetList = tecardMapper.getSheetDetail(tecard);
        for (Tecard tecard1 : craSheetList) {
            if (tecard1.getProdChange() == 1) {
                /** 变更逻辑通过Id查询出生产工艺卡主表里面的数据*/
                FlowSheet flowSheetObj = tecardMapper.findFlowSheetId(tecard1.getId());
                if (null != flowSheetObj) {
                    //检测要接收的工艺卡的格式是否正确
                    List<Tecard> allRouteData = tecardMapper.findAbnormalDataByCardId(tecard1.getId());
                    Tecard lastRoute = allRouteData.get(allRouteData.size() - 1);
                    for (int i = 0; i < allRouteData.size() - 1; i++) {
                        if (allRouteData.get(i).getOrderNo().intValue() >= lastRoute.getOrderNo().intValue()) {
                            return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" +"该工艺卡格式非法，序号错误，无法进行接收！<br>";
                        }
                    }
                    for (int i = 0; i < allRouteData.size() - 1; i++) {
                        if (allRouteData.get(i).getRoute().equals(lastRoute.getRoute())) {
                            return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡格式非法，尾序路线位置不正确，无法进行接收！<br>";
                        }
                    }
                    for (int i = 0; i < allRouteData.size(); i++) {
                        Tecard comparator = allRouteData.get(i);
                        for (int j = 0; j < allRouteData.size(); j++) {
//                            if (comparator.getOrderNum().intValue() < allRouteData.get(j).getOrderNum().intValue() &&
//                                    comparator.getOrderNo() >= allRouteData.get(j).getOrderNo()) {
//                                return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡格式非法，无法进行接收！<br>";
//                            }
                            if (comparator.getOrderNo().intValue() == allRouteData.get(j).getOrderNo().intValue() &&
                                    !comparator.getRoute().equals(allRouteData.get(j).getRoute())) {
                                return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡格式非法，序号错误，无法进行接收！<br>";
                            }
                        }
                    }
                    /** 通过Id查询技术文件工艺卡明细表里面的明细集合*/
                    List<Tecard> byCardId = tecardMapper.findByCardId(tecard1.getId());
                    int notRouteNum = 0;
                    /** 变更后的查询从表去重明细*/
                    List<Tecard> newList = byCardId.stream().filter(distinctByKey(Tecard::getOrderNo)).collect(Collectors.toList());
                    //按照重写的比较方法进行排序
                    Collections.sort(newList, new Comparator<Tecard>() {
                        @Override
                        public int compare(Tecard o1, Tecard o2) {
                            return o1.getOrderNum() - o2.getOrderNum();
                        }
                    });
                    /** 通过Id查询flowRoute路线明细*/
                    List<FlowRoute> flowRoutes = tecardMapper.findFlowRoutes(flowSheetObj.getId());
                    List<FlowRoute> transpositionFlowRoutes = new ArrayList<>();
                    //获取已转序的列表
                    for (int i = 0; i < flowRoutes.size(); i++) {
                        if (flowRoutes.get(i).getStatus() != 1) {
                            transpositionFlowRoutes.add(flowRoutes.get(i));
                        }
                    }

//                    if (transpositionFlowRoutes.size() > 0) {
//                        if (transpositionFlowRoutes.size() == newList.size()) {
//                            return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡全部已转完序，无法进行接收！<br>";
//                        } else if (transpositionFlowRoutes.size() > newList.size()) {
//                            return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡要变更的路线已转完序，无法进行接收！<br>";
//                        } else if (transpositionFlowRoutes.size() < newList.size()) {
//                            //判断变更的序中是否有已转完的序或者全部转完的序
//                            for (int i = 0; i < transpositionFlowRoutes.size(); i++) {
//                                if (!transpositionFlowRoutes.get(i).getRoute().equals(newList.get(i).getRoute())) {
//                                    return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡要变更的路线已转完序，无法进行接收！<br>";
//                                }
//                                if (transpositionFlowRoutes.get(i).getOrderNo().intValue() != newList.get(i).getOrderNo().intValue()) {
//                                    return "接收失败！工艺卡图号为【" + tecard1.getDrawNo() + "】名称为【" + tecard1.getDrawName() + "】的异常信息如下：<br>" + "该工艺卡要变更的路线已转完序，无法进行接收！<br>";
//                                }
//                            }
//                        }
//                    }

                }
            }
        }
        if (!result.equals("")) {
            return result;
        } else {
            return "pass";
        }
    }
}
